package datamodel;

import java.util.ArrayList;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;

@XStreamAlias("Sudoku")
public class Grid implements Observer {

	public static String NAME = "grid";
	public static String XMAX = "xMax";
	public static String YMAX = "yMax";

	@XStreamAsAttribute
	private int xMax, yMax, numberOfPossibleValues;
	//@XStreamImplicit(itemFieldName="row")
	private ArrayList<ArrayList<Field>> grid;
	@XStreamOmitField
	private long lastChange;

	public Grid(int xMax, int yMax, int numberOfSigns) {
		ArrayList<Field> newRow;
		this.numberOfPossibleValues = numberOfSigns;
		this.xMax = xMax;
		this.yMax = yMax;

		grid = new ArrayList<ArrayList<Field>>(yMax);

		for (int y = 0; y < yMax; y++) {
			newRow = new ArrayList<Field>();
			for (int x = 0; x < xMax; x++) {
				newRow.add(FieldFactory.getInitializedField(this));
			}
			grid.add(newRow);
		}
	}

	public void init() {
		for (int y = 0; y < yMax; y++) {
			for (int x = 0; x < xMax; x++) {
				if(getField(x, y).getValue() == Field.EMPTY) {
					getField(x,y).init(numberOfPossibleValues);
					getField(x,y).observe(this);
				}
			}
		}
	}
	
	public int getNumberOfPossibleValues() {
		return this.numberOfPossibleValues;
	}
	
	public Field getField(int x, int y) {
		return grid.get(y).get(x);
	}

	public void setField(int x, int y, Field f) {
		grid.get(y).set(x, f);
	}

	@Override
	public String toString() {
		String s = new String();
		s=s.concat("xMax: " + this.xMax + "\n");
		s=s.concat("yMax: " + this.yMax + "\n");
		s=s.concat("numberOfPossibleValues: " + this.numberOfPossibleValues + "\n");
		for (int y = 0; y < this.yMax; y++) {
			for (int x = 0; x < this.xMax; x++) {
				s = s.concat(getField(x, y).toString());
			}
			s = s.concat("\n");
		}
		return s;
	}

	public int getXMax() {
		return this.xMax;
	}

	public int getYMax() {
		return this.yMax;
	}

	@Override
	public void notifyChange() {
		lastChange = System.currentTimeMillis();
	}

	public long getLastChange() {
		return lastChange;
	}
}